package com.quanyan.club.service.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.quanyan.activity.request.ReqGroupVo;
import com.quanyan.activity.response.GroupData;
import com.quanyan.activity.response.GroupInfo;
import com.quanyan.activity.response.RespActivityPoster;
import com.quanyan.activity.response.RespGroupInfo;
import com.quanyan.api.APIResponse;
import com.quanyan.club.constants.ClubConstants;
import com.quanyan.club.entity.db.*;
import com.quanyan.club.entity.vo.msg.ActivityRelatedMsg;
import com.quanyan.club.entity.vo.req.ReqSignUpDetail;
import com.quanyan.club.entity.vo.resp.RespClubActivity;
import com.quanyan.club.entity.vo.resp.RespClubFinanceBillDetail;
import com.quanyan.club.entity.vo.resp.RespSearchActivity;
import com.quanyan.club.mapper.*;
import com.quanyan.club.mq.producer.ClubXpLevelProducer;
import com.quanyan.club.pullclub.service.PullClubSupportService;
import com.quanyan.club.service.*;
import com.quanyan.club.sms.ClubSmsService;
import com.quanyan.club.task.TimerTaskJob;
import com.quanyan.club.util.ActivityUtils;
import com.quanyan.club.util.ClubNameUtils;
import com.quanyan.comment.enums.TaskEnum;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.http.HttpClientUtils;
import com.quanyan.common.utils.*;
import com.quanyan.im.entity.req.ModifyIMGroup;
import com.quanyan.mq.client.QcMsgClient;
import com.quanyan.mq.client.reqeust.MqRequestMsg;
import com.quanyan.place.client.PlaceClient;
import com.quanyan.place.entity.PlaceDubboProvider;
import com.quanyan.search.entity.response.ActivitySearchResponse;
import com.quanyan.search.entity.vo.ActivityIndexInfo;
import com.quanyan.search.service.ActivitySearchService;
import com.quanyan.search.service.impl.ActivitySearchServiceImpl;
import com.quanyan.user.mq.UserTaskMsg;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.serviceFacade.UserServiceFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by yue.yuan on 2016/11/30.
 */
@Service("activitySupportService")
public class ActivitySupportServiceImpl extends BaseServiceImpl implements ActivitySupportService {

    @Autowired
    private ClubXpLevelService clubXpLevelService;
    @Autowired
    private TimerTaskJob timerTaskJob;
    @Autowired
    @Qualifier("personCenterTaskClient")
    private QcMsgClient personCenterTaskClient;
    @Autowired
    private ClubSearchBizService clubSearchBizService;
    @Autowired
    private CppService cppService;
    @Autowired
    private ClubXpLevelProducer clubXpLevelProducer;
    private final String POST_ACTIVITY = "POST_ACTIVITY";
    @Value("${group.IM.service.url}")
    private String groupIMServiceUrl;
    @Autowired
    private PlaceClient placeClient;
    @Autowired
    private ClubFinanceMgmService clubFinanceMgmService;
    @Autowired
    private UserServiceFacade userServiceFacade;
    @Autowired
    private TbSignUserMapper signUserMapper;
    @Autowired
    private TbOrderMapper orderMapper;
    @Autowired
    private TbActivityPosterMapper tbActivityPosterMapper;
    @Autowired
    private ClubActivityCRUDMapper clubActivityCRUDMapper;
    @Autowired
    private ClubIntegralService clubIntegralService;
    @Autowired
    private ClubMemberMapper cumstomClubMemberMapper;
    @Autowired
    private ClubSmsService clubSmsService;
    @Autowired
    private TbCategoryMapper tbCategoryMapper;
    @Autowired
    private TbClubMemberMapper clubMemberMapper;
    @Autowired
    private PullClubSupportService pullClubSupportService;
    @Autowired
    private TbClubMapper tbClubMapper;
    @Autowired
    private TbClubActivityMapper tbClubActivityMapper;
    @Autowired
    private ClubFirstOrderTaskService clubFirstOrderTaskService;
    @Autowired
    private TbActivityMapper tbActivityMapper;
    @Autowired
    private TbClubTaskSummaryLogMapper tbClubTaskSummaryLogMapper;
    @Autowired
    private TbActivityDescMapper tbActivityDescMapper;

    private static final Logger logger =
            LoggerFactory.getLogger(ActivitySupportServiceImpl.class);

    @Override
    @Async
    public void afterSaveActivity(RespClubActivity respClubActivity, TbClub tbClub, boolean isFirst) {
        if(isFirst) {
            TbChannelUser tbChannelUser = pullClubSupportService.isPullUser(tbClub.getUid(),
                    tbClub, respClubActivity.getActivityId(),
                    ClubConstants.PULL_STATUS_ACTIVITY, new Date());
            if(null == tbChannelUser) {
                logger.warn("找不到拉新用户");
            } else {
                logger.warn(JSONObject.toJSONString(tbClub));
                tbChannelUser.setClubId(respClubActivity.getClubId());
                logger.warn("更新拉新状态并更新目标俱乐部：" + respClubActivity.getClubId());
                pullClubSupportService.updatePullStatus(tbChannelUser,
                        ClubConstants.PULL_STATUS_ACTIVITY);
            }
        }

        addActivityIndex4Solr(respClubActivity); //增加solr索引

        submitActivityCreatedJob(respClubActivity.getActivityId(), respClubActivity.getClubId(),
                respClubActivity.getActivityType(), respClubActivity.getStartTime(),
                respClubActivity.getSignEndTime()); ////活动创建成功，提交定时任务

        this.pushActivityUserCenterTaskMsg(
                respClubActivity.getUid(), TaskEnum.TASK_ENUM__CREATE_ACTIVITY.getId());
        //创建时，俱乐部索引活动个数+1
        clubSearchBizService.updateSignupActivityCountOfClubIndex(respClubActivity.getClubId(), 1);
        //活动结束时通知成员
        submitActivityEndJob(respClubActivity);
        logger.warn("进入俱乐部自动结算定时任务提交");
        submitActivitySettlementJob(respClubActivity.getEndTime(),
                respClubActivity.getClubId(), respClubActivity.getId());
        cppService.pushCreateActivity(respClubActivity);
    }

    @Override
    @Async
    public void afterUpdateActivity(RespClubActivity respClubActivity) {

        //增加solr索引
        if (respClubActivity.getActivityId() == null) {
            logger.warn("activity is null");
            return;
        }
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        activitySearchService.deleteDocById(respClubActivity.getActivityId());
        addActivityIndex4Solr(respClubActivity); //增加solr索引
        submitActivitySettlementJob(respClubActivity.getEndTime(),
                respClubActivity.getClubId(), respClubActivity.getActivityId());
        ModifyIMGroup modifyIMGroup = new ModifyIMGroup();
        modifyIMGroup.setCurrentUid(respClubActivity.getUid());
        modifyIMGroup.setGroupid(respClubActivity.getGroupId());
        modifyIMGroup.setExtid(respClubActivity.getActivityId());
        modifyIMGroup.setGroupname(respClubActivity.getName());
        modifyIMGroup.setGroupdescriptions(respClubActivity.getName());
        cppService.modifyGroup(modifyIMGroup);
        cppService.pushUpdateActivity(respClubActivity);
        submitActivityCreatedJob(respClubActivity.getActivityId(), respClubActivity.getClubId(),
                respClubActivity.getActivityType(), respClubActivity.getStartTime(),
                respClubActivity.getSignEndTime()); ////活动创建成功，提交定时任务
        //活动结束时通知成员
        submitActivityEndJob(respClubActivity);
    }

    @Override
    @Async
    public void afterReSuspendActivity(RespClubActivity respClubActivity) {
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        logger.info("----------恢复暂停的活动------");
        addActivityIndex4Solr(respClubActivity);
        clubSearchBizService.updateSignupActivityCountOfClubIndex(respClubActivity.getClubId(), 1);
        logger.info("----------从俱乐部索引恢复暂停的活动个数------");
    }

    @Override
    @Async
    public void afterSuspendActivity(int activityId, int clubId) {
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        APIResponse responseSolr=activitySearchService.deleteDocById(activityId);
        logger.info("----------暂停活动-从搜索引擎下架------" + JSONObject.toJSONString(responseSolr));
        clubSearchBizService.updateSignupActivityCountOfClubIndex(clubId, -1);
        logger.info("----------暂停活动-从俱乐部搜索引擎下架------");
    }

    @Override
    @Async
    public void afterCancelActivity(RespClubActivity respClubActivity, int larkAppId) {

        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        activitySearchService.deleteDocById(respClubActivity.getActivityId());
        //推送取消活动消息
        cppService.pushCancelActivity(respClubActivity,larkAppId);
        clubSearchBizService.updateSignupActivityCountOfClubIndex(respClubActivity.getClubId(), -1);
    }

    @Override
    @Async
    public void afterSignUpActivity(RespClubActivity respClubActivity,
                                    int currentUserId,
                                    String address, String mobile, String clubName, int larkAppId) {
        clubSmsService.sendSms(mobile, ClubSmsService.CLUB_MESSAGE_TEMPLATE_PLACE_ACTIVITY_NOTICE,
                Arrays.asList(clubName,
                respClubActivity.getName(),
                DateUtils.convertDateToString(respClubActivity.getStartTime()), address));
        cppService.pushActivitySignUp(respClubActivity, currentUserId, larkAppId);
        List<Integer> clubAdminUids = cumstomClubMemberMapper.selectClubAdminsByClubId(
                respClubActivity.getClubId());
        //推送给管理员报名通知
        if (CollectionUtils.isNotEmpty(clubAdminUids)) {
            pushNotify(respClubActivity, currentUserId, 1, clubAdminUids);
        }
    }

    @Override
    @Async
    public void afterRefundActivity(RespClubActivity respClubActivity,
                                    int orderUid, String businessOrderNo, int orderId) {

        boolean result = cppService.addOrDelIMGroupMember(respClubActivity.getUid(),
                respClubActivity.getActivityId(), respClubActivity.getGroupId(),
                Lists.newArrayList(orderUid), false);
        logger.warn("6 将此人{}剔除活动聊天组{}，返回：{}", orderUid, respClubActivity.getGroupId(), result);
        cppService.pushCancelActivityOrder(respClubActivity, orderUid, orderId);
        cppService.pushRefundActivityOrder(respClubActivity, orderUid, businessOrderNo);
    }

    @Override
//    @Async
    public void afterSettlementActivity(boolean isAuto, int userId,
                                        RespClubActivity respClubActivity, List<TbOrder> needRefundOrders) {

        pullService(respClubActivity, needRefundOrders);
//        try {
//            clubFirstOrderTaskService.firstOrderAward(respClubActivity.getClubId(),
//                    respClubActivity.getActivityId());
//        } catch (Exception e) {
//            e.printStackTrace();
//            logger.warn("sd: 调用俱乐部首单奖励任务失败异常：" + e.getMessage());
//        }

        TbClubMemberExample example = new TbClubMemberExample();
        TbClubMemberExample.Criteria criteria = example.createCriteria();
        criteria.andClubIdEqualTo(respClubActivity.getClubId())
                .andRoleCodeIn(Arrays.asList(Constants.ClubRole.CLUB_ROLE_PRESIDENT,
                        Constants.ClubRole.ROLE_CLUB_FINANCIAL))
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> members = clubMemberMapper.selectByExample(example);
        List<Integer> list = new ArrayList<>();
        for (TbClubMember member : members) {
            list.add(member.getUid());
        }
        if (!isAuto) {
            pushNotify(respClubActivity, userId, 3, list);
        } else {
            pushNotify(respClubActivity, userId, 4, list);
        }
        submitAutoAppraiseJob(respClubActivity.getActivityId());
        cppService.pushActivityEndingMsg(respClubActivity.getActivityId(),
                respClubActivity.getLogoUrl(), respClubActivity.getFeeType(),
                respClubActivity.getRespActivityPoster().getUrl(), respClubActivity.getName());
        logger.warn("已经推送活动结束消息给报名人，活动ID：" + respClubActivity.getActivityId());
    }

    private void pullService(RespClubActivity respClubActivity,
                             List<TbOrder> needRefundOrders) {
        Integer activityId = respClubActivity.getActivityId();
        TbClub club = tbClubMapper.selectByPrimaryKey(respClubActivity.getClubId());
        int firstClubId = clubActivityCRUDMapper.firstClubActivity(club.getUid());
        if(club.getId() != firstClubId) {
            logger.warn("拉新条件：完成奖励俱乐部是第一个创建活动的俱乐部---FAIL:firstClubId"
                    + firstClubId);
            return;
        }
        if(respClubActivity.getLowestPrice().compareTo(
                BigDecimal.valueOf(pullClubSupportService.getSignFee())) == -1) {
            logger.warn("拉新条件：活动最低价格---FAIL：" + respClubActivity.getLowestPrice());
            return;
        }
        TbActivity tbActivity = tbActivityMapper.selectByPrimaryKey(activityId);
        TbChannelUser tbChannelUser = pullClubSupportService.isPullUser(club.getUid(),
                club, activityId, ClubConstants.PULL_STATUS_SUCCESS, tbActivity.getCreateTime());
        if(null == tbChannelUser) {
            logger.warn("拉新条件：主席为渠道拉新用户---FAIL：clubUid:" + club.getUid());
            return;
        }
        List<Integer> signUsers = new ArrayList<Integer>();
        for(TbOrder order : needRefundOrders) {
            signUsers.add(order.getOrderUid());
        }
        if(needRefundOrders.size() <
                pullClubSupportService.getSignCountsSetting(ClubConstants.RULE_SETTING_PULL_GRADE)) {
            logger.warn("拉新条件：有效订单数量---FAIL,orderSize:" + needRefundOrders.size());
            return;
        }
        logger.warn("基本校验条件通过，开始进入拉新成功逻辑------");
        //是否拉新成功
        pullClubSupportService.pullUserSuccess(tbChannelUser, respClubActivity, club, signUsers);
    }

    public void afterCreateWeekRange(RespClubActivity respClubActivity) {
        try {
            addActivityIndex4Solr(respClubActivity); //增加solr索引
            clubSearchBizService.updateSignupActivityCountOfClubIndex(respClubActivity.getClubId(), 1);

            submitActivityCreatedJob(respClubActivity.getActivityId(), respClubActivity.getClubId(),
                    respClubActivity.getActivityType(), respClubActivity.getStartTime(), respClubActivity.getSignEndTime()); ////活动创建成功，提交定时任务
            submitActivitySettlementJob(respClubActivity.getEndTime(),
                    respClubActivity.getClubId(), respClubActivity.getActivityId());
            submitActivityEndJob(respClubActivity);

            pushActivityUserCenterTaskMsg(
                    respClubActivity.getUid(), TaskEnum.TASK_ENUM__CREATE_ACTIVITY.getId());

        } catch (Exception e) {
            logger.error("活动创建成功，后续任务失败：{}", e.getMessage());
        }
    }

    public void addActivityIndex4Solr(RespClubActivity respClubActivity)
    {
        ActivitySearchService activitySearchService = new ActivitySearchServiceImpl(searchCloudUrl);
        ActivityIndexInfo activityIndexInfo = new ActivityIndexInfo();
        activityIndexInfo.setActivity_placeAddress(respClubActivity.getPlaceAddress());
        activityIndexInfo.setActivity_categorieId(respClubActivity.getCategoryId());
        activityIndexInfo.setActivity_categorieName("");
        if (null != respClubActivity.getPlaceDubboProvider()) {
            activityIndexInfo.setActivity_site(respClubActivity.getPlaceDubboProvider().getName());
        }
        activityIndexInfo.setActivity_cityId(respClubActivity.getCityId());
        activityIndexInfo.setActivity_districtId(respClubActivity.getDistrictId());
        activityIndexInfo.setActivity_lat(respClubActivity.getLat());
        activityIndexInfo.setActivity_lng(respClubActivity.getLng());
        activityIndexInfo.setActivity_clubName(respClubActivity.getClubName());
        List<Integer> dateParams = new ArrayList<>();
        ActivityUtils.getDateParams(dateParams, respClubActivity);
        activityIndexInfo.setActivity_dateParams(dateParams);
        activityIndexInfo.setActivity_deadlineTime(respClubActivity.getSignEndTime());
        activityIndexInfo.setActivity_startTime(respClubActivity.getStartTime());
        activityIndexInfo.setActivity_endTime(respClubActivity.getEndTime());
        activityIndexInfo.setActivity_id(respClubActivity.getActivityId() + "");
        if (null != respClubActivity.getSignUserList() && respClubActivity.getLimitNum() > 0) {
            activityIndexInfo.setActivity_isFull(respClubActivity.getSignUserList().size()
                    >= respClubActivity.getLimitNum() ? 1 : 0);
        } else {
            activityIndexInfo.setActivity_isFull(0);//未报满
        }
        activityIndexInfo.setActivity_isPrime(respClubActivity.getIsPrimeTime().intValue());
        activityIndexInfo.setActivity_name(respClubActivity.getName());
        if (null != respClubActivity.getFeeType()) {//收费类型   0 AA收费，1 会员制
            if (respClubActivity.getFeeType().equals(Constants.BYTE_ZERO)) {
                activityIndexInfo.setActivity_price(respClubActivity.getAaFee().doubleValue());
            } else {
                List<Double> doubles = new ArrayList<>();
                doubles.add(respClubActivity.getFemaleMemberFee().doubleValue());
                doubles.add(respClubActivity.getMaleMemberFee().doubleValue());
                if(null == respClubActivity.getSignUpType() || respClubActivity.getSignUpType().equals(Constants.BYTE_ZERO))
                {
                    doubles.add(respClubActivity.getFemaleFee().doubleValue());
                    doubles.add(respClubActivity.getMaleFee().doubleValue());
                }
                activityIndexInfo.setActivity_price(CommonUtils.mathUtil(doubles));
            }
        }
        if (null != respClubActivity.getRespActivityPoster()) {
            activityIndexInfo.setActivity_url(respClubActivity.getRespActivityPoster().getUrl());
        }
        String activityPY = ClubNameUtils.getClubNamePinYin(respClubActivity.getName());
        String clubPY = ClubNameUtils.getClubNamePinYin(respClubActivity.getClubName());
        String activityFirst = activityPY.substring(0, 1);
        String clubFirst = clubPY.substring(0, 1);
        activityIndexInfo.setActivity_clubName_first_letter(clubFirst);
        activityIndexInfo.setActivity_clubName_pinyin(clubPY);
        activityIndexInfo.setActivity_name_first_letter(activityFirst);
        activityIndexInfo.setActivity_name_pinyin(activityPY);
        isClubTask(respClubActivity);
        activityIndexInfo.setClubTask(respClubActivity.getClubTask());
        logger.warn("=====================>开始插入活动索引<==================");
        activitySearchService.insertDoc(activityIndexInfo);
    }

    public void isClubTask(RespClubActivity respClubActivity) {
        TbClubTaskSummaryLogExample summaryLogExample =
                new TbClubTaskSummaryLogExample();
        summaryLogExample.createCriteria()
                .andIsFinishTaskEqualTo(true)
                .andClubIdEqualTo(respClubActivity.getClubId())
                .andCreateTimeGreaterThan(DateUtils.getTimesWeekmorning(new Date()));
        int count = tbClubTaskSummaryLogMapper.countByExample(summaryLogExample);
        respClubActivity.setClubTask(count == 0 ? count : 1);
    }

    @Override
    @Async
    public void afterAppraise(TbClubActivity clubActivity, TbActivity activity,
                              int userId, double addScore) {
        int clubId = clubActivity.getClubId();
        logger.warn("开始调用积分，入参：clubId" + clubId + "addScore:" + addScore/2.0);
        clubIntegralService.modifyClubCommentStar(clubId, addScore/2.0);
        pushActivityUserCenterTaskMsg(userId, TaskEnum.TASK_ENUM__COMMENT_ACTIVITY.getId());
        RespClubActivity respClubActivity = new RespClubActivity();
        respClubActivity.setActivityId(clubActivity.getActivityId());
        respClubActivity.setClubId(clubId);
        respClubActivity.setName(activity.getName());
        respClubActivity.setPosterPicId(activity.getPosterPicId());
        pushNotify(respClubActivity, userId, 2,Lists.<Integer>newArrayList(clubActivity.getUid()));
    }

    @Override
    public void pushActivityUserCenterTaskMsg(int uid, Integer taskId) {
        UserTaskMsg userTaskMsg = new UserTaskMsg();
        userTaskMsg.setTaskId(taskId);
        userTaskMsg.setUid(uid);
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setTopic(Constants.MQ_TOPIC_TASK_TOPIC);
        mqRequestMsg.setTag(Constants.MQ_TOPIC_TASK_TAG);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(userTaskMsg));
        personCenterTaskClient.syncSend(mqRequestMsg);
    }

    @Async
    public void pushNotify(RespClubActivity respClubActivity,
                            Integer uid,
                            Integer type,
                            List<Integer> toUid) {
        //批量查询用户信息
        APIResponse<List<RespUserInfoBase>> respUserInfoBase =
                userServiceFacade.batchQueryUserInfo(Lists.<Integer>newArrayList(uid));
        if (!respUserInfoBase.isRet() || CollectionUtils.isEmpty(respUserInfoBase.getData())) {
            return;
        }

        RespUserInfoBase userInfoBase = respUserInfoBase.getData().get(0);
        ActivityRelatedMsg activityRelatedMsg = new ActivityRelatedMsg();
        activityRelatedMsg.setActivityId(respClubActivity.getActivityId());
        activityRelatedMsg.setActivityName(respClubActivity.getName());
        activityRelatedMsg.setAvatar(userInfoBase.getIcon());
        activityRelatedMsg.setClubName(respClubActivity.getClubName());
        activityRelatedMsg.setClubId(respClubActivity.getClubId());
        activityRelatedMsg.setToUid(toUid);
        activityRelatedMsg.setUserNick(userInfoBase.getNickName());
        activityRelatedMsg.setPosterId(respClubActivity.getPosterPicId());

        if (type == 1) {
            cppService.pushActivitySignUpSuccess(activityRelatedMsg);
        } else if (type == 2) {
            cppService.pushActivityAppraise(activityRelatedMsg);
        } else if (type == 3) {
            RespClubFinanceBillDetail respClubFinanceBillDetail =
                    clubFinanceMgmService.getClubFinanceBillDetail(
                            activityRelatedMsg.getActivityId(),
                            activityRelatedMsg.getClubId(), Constants.IS_YES);
            if (respClubFinanceBillDetail == null) {
                logger.warn("没有活动结算详情");
                return;
            }
            cppService.pushActivitySettlement(activityRelatedMsg, respClubFinanceBillDetail);
        } else if (type == 4) {
            RespClubFinanceBillDetail respClubFinanceBillDetail =
                    clubFinanceMgmService.getClubFinanceBillDetail(
                            activityRelatedMsg.getActivityId(),
                            activityRelatedMsg.getClubId(), Constants.IS_YES);
            if (respClubFinanceBillDetail == null) {
                logger.warn("没有活动结算详情");
                return;
            }
            cppService.pushActivityAutoSettle(activityRelatedMsg, respClubFinanceBillDetail);
        }
    }

    /**
     * 俱乐部活动结束时检查是否正常结束并推送通知
     */
    private void submitActivityEndJob(RespClubActivity respClubActivity) {
        Map<String, String> param = new HashMap<>();
        param.put("activityId", String.valueOf(respClubActivity.getActivityId()));
        param.put("logoUrl", String.valueOf(respClubActivity.getLogoUrl()));
        param.put("feeType", String.valueOf(respClubActivity.getFeeType()));
        param.put("posterUrl", String.valueOf(respClubActivity.getRespActivityPoster().getUrl()));
        param.put("name", String.valueOf(respClubActivity.getName()));
        param.put("clubId", String.valueOf(respClubActivity.getClubId()));
        param.put("categoryId", String.valueOf(respClubActivity.getCategoryId()));
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(respClubActivity.getEndTime());
        cal.set(Calendar.SECOND, 0);
        timerTaskJob.submitTask(param,
                ClubConstants.CLUB_JOB_ID_ACTIVITY_END_NOTIFY + respClubActivity.getActivityId(), //保证唯一
                cal.getTimeInMillis(), 0);

        logger.warn("提交俱乐部活动结束定时任务完成。", respClubActivity.getActivityId());
    }
    //活动结束后七天未评价，则自动评价
    public void submitAutoAppraiseJob(int activityId)
    {
        logger.warn("开始提交俱乐部活动结束七天后自动评价任务");
        Map<String, String> param = new HashMap<>();
        param.put("activityId", String.valueOf(activityId));
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(new Date());
        //cal.add(Calendar.MINUTE, 10);//七天后    十分钟后 测试用
        cal.add(Calendar.DAY_OF_WEEK, 7);//七天后    十分钟后 测试用
        long repeatInterval = 0;
        timerTaskJob.submitTask(param,
                ClubConstants.CLUB_JOB_ID_ACTIVITY_AUTO_APPRAISE + activityId, //保证唯一
                cal.getTimeInMillis(), repeatInterval);
        logger.warn("提交俱乐部活动结束自动评价定时任务完成。", activityId);

    }


    //活动结束后执行自动结算
    private void submitActivitySettlementJob(Date activityEndTime, int clubId, int activityId)
    {
        if(null == activityEndTime || clubId == 0 || activityId == 0)
        {
            logger.warn("活动定时自动结算有问题：" + "activityEndTime:" + activityEndTime +
                    "clubId" + clubId + "activityId" + activityId);
            throw new BizException("这个活动已经夭折，请重新孵化。");
        }
        Map<String, String> param = new HashMap<>();
        param.put("clubId", String.valueOf(clubId));
        param.put("activityId", String.valueOf(activityId));
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(activityEndTime);
        cal.add(Calendar.HOUR, 6);//6小时后
        long repeatInterval = 0;
        timerTaskJob.submitTask(param,
                ClubConstants.CLUB_JOB_ID_ACTIVITY_SETTLE + activityId, //保证唯一
                cal.getTimeInMillis(), repeatInterval);
        logger.warn("提交俱乐部活动结束自动结算定时任务完成。", activityId);
    }

    /**
     * 俱乐部活动创建成功后，提交两个定时任务 1. 在活动开始半小时前，发送活动开始通知给已报名用户 2. 在活动报名截止时，检查此活动是否可以开启，不能开启，取消活动，退款给已报名用户
     */
    private void submitActivityCreatedJob(int activityId, int clubId, int activityType, Date activityStartTime, Date signEndTime) {

        Map<String, String> param = new HashMap<>();
        param.put("clubId", String.valueOf(clubId));
        param.put("activityId", String.valueOf(activityId));
        long repeatInterval = 0;
        Calendar cal = Calendar.getInstance();
        //启动定时器：1. 在此活动的开始时间的前半个小时执行，计算此活动的已报名人数，如果此活动的报名人数已满，发送活动开始通知给报名人
        cal.setTime(activityStartTime);
        cal.add(Calendar.MILLISECOND, -1 * 30 * 60 * 1000); //活动开始前半小时
        long executeTime = cal.getTimeInMillis();
        if (activityStartTime.getTime() - new Date().getTime() < 30 * 60 * 1000) {
            executeTime = activityStartTime.getTime();
        }
        timerTaskJob.submitTask(param,
                ClubConstants.CLUB_JOB_ID_ACTIVITY_START_NOTIFY + activityId, //保证唯一
                executeTime,
                repeatInterval);

        //启动定时器：2. 在此活动的报名截止时间点执行，计算此活动的已报名人数，如果报名人数未满，取消此活动，退款给已报名的用户
        if (activityStartTime.equals(signEndTime)) {
            cal.clear();
            cal.setTime(signEndTime);
            cal.add(Calendar.SECOND, -15);  //计算活动报名截止时间，如果活动开始时间等于报名截止时间，提前15秒钟检查
            signEndTime = cal.getTime();
        }
        logger.warn("俱乐部活动{}创建成功，提交定时任务完成。", activityId);
    }


    //活动评价校验
    public APIResponse validAppraise(TbActivity tbActivity, TbClubActivity tbClubActivity,
                                      int userId, String businessOrderNo)
    {
        if(!tbClubActivity.getIsSettle().equals(Constants.BYTE_ONE))
        {
            return APIResponse.returnFail("活动还没结算，无法评价");
        }
        TbSignUserExample example = new TbSignUserExample();
        example.createCriteria().andActivityIdEqualTo(tbActivity.getId()).
                andOrderUserIdEqualTo(userId).andIsCancelEqualTo(0).andStatusEqualTo(1);
        example.setLimit(Limit.buildLimit(1, 1));
        List<TbSignUser> tbSignUsers = signUserMapper.selectByExample(example);
        if (com.alibaba.dubbo.common.utils.CollectionUtils.isEmpty(tbSignUsers)) {
            return APIResponse.returnFail("你还没报名该活动");
        }
        TbSignUser tbSignUser = tbSignUsers.get(0);
        if(tbSignUser.getManageType() != 4)
        {
            return APIResponse.returnFail("你都没有去参加这个活动，不好妄下论断吧。");
        }

        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria().andOrderNoEqualTo(businessOrderNo)
                .andOrderUidEqualTo(userId)
                .andActivityIdEqualTo(tbActivity.getId());
        List<TbOrder> orders = orderMapper.selectByExample(orderExample);
        if (com.alibaba.dubbo.common.utils.CollectionUtils.isEmpty(orders)) {
            return APIResponse.returnFail("订单不存在");
        }
        TbOrder tbOrder = orders.get(0);

        //0超时未支付 1待支付 2支付成功 3支付失败 4退款中 5退款完成 6:AA退款完成 7已评价 8已取消
        if (tbOrder.getOrderStatus().equals((byte) 1)
                || tbOrder.getOrderStatus().equals((byte) 3)
                || tbOrder.getOrderStatus().equals((byte) 4)
                || tbOrder.getOrderStatus().equals((byte) 5)
                || tbOrder.getOrderStatus().equals((byte) 8)) {
            return APIResponse.returnFail("无效订单, 评价失败");
        }

        if (tbOrder.getOrderStatus().equals((byte) 7)) {
            return APIResponse.returnFail("你已经评价过该活动了");
        }
        tbOrder.setOrderStatus((byte) 7);
        orderMapper.updateByPrimaryKeySelective(tbOrder);
        return APIResponse.returnSuccess();
    }

    public String createGroup(String activityName,Integer plannerUid, String posterUrl)
    {
        ReqGroupVo reqGroupVo = new ReqGroupVo();
        reqGroupVo.setVer("1.0");
        reqGroupVo.setProtocol_ver(Integer.valueOf(1));
        reqGroupVo.setCurrentUid(plannerUid);
        reqGroupVo.setApproval(Byte.valueOf((byte)0));
        reqGroupVo.setGroupdescriptions(activityName);
        reqGroupVo.setGroupname(activityName);
        reqGroupVo.setHead(posterUrl);
        reqGroupVo.setIspublic(Byte.valueOf((byte)0));
        reqGroupVo.setType(Byte.valueOf((byte)3));
        reqGroupVo.setMaxusers(500);
        reqGroupVo.setOwner(plannerUid);
        RespGroupInfo respGroupVo = new RespGroupInfo();
        try
        {
            String postJson = JSON.toJSONString(reqGroupVo);
            logger.warn("调用C端接口传参：groupIMServiceUrl:" + this.groupIMServiceUrl + "  postJson:" + postJson);
            String result = HttpClientUtils.postJson(this.groupIMServiceUrl, postJson);
            logger.warn("调用C端接口返回json字符串：result:" + result);
            Gson gson = new Gson();
            respGroupVo = (RespGroupInfo)gson.fromJson(result, RespGroupInfo.class);
        }
        catch (Exception e)
        {
            logger.error("创建活动聊天群组失败，原因:{}", e);
            return null;
        }
        if (null == respGroupVo) {
            return null;
        }
        GroupData groupData = respGroupVo.getData();
        if (null == groupData)
        {
            return null;
        }
        List<GroupInfo> groupInfos = groupData.getGroupinfo();
        if (CollectionUtils.isEmpty(groupInfos)) {
            return null;
        }
        GroupInfo info = (GroupInfo)groupInfos.get(0);
        return info.getGroupid();
    }

    public PlaceDubboProvider getActivityPlace(Integer placeId)
    {
        try {
            Map<Integer, PlaceDubboProvider> map =
                    placeClient.getPlaceBySinglePlaceId(placeId);
            if (null != map && null != map.get(placeId)) {
                return map.get(placeId);
            }
        } catch (RpcException re) {
            logger.warn("调用场馆返回空值。" + re.getMessage());
            return null;
        }
        return null;
    }

    public void getActivityPlace(RespClubActivity respClubActivity)
    {
        if (null != respClubActivity.getPlaceId() && respClubActivity.getPlaceId() != 0) {
            try {
                Map<Integer, PlaceDubboProvider> map =
                        placeClient.getPlaceBySinglePlaceId(respClubActivity.getPlaceId());
                if (null != map && null != map.get(respClubActivity.getPlaceId())) {
                    PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                    if (null != map.get(respClubActivity.getPlaceId())) {
                        BeanCopierUtils.copyProperties(map.get(respClubActivity.getPlaceId()), placeDubboProvider);
                    }
                    respClubActivity.setPlaceDubboProvider(placeDubboProvider);
                    map.clear();
                }
            } catch (RpcException re) {
                logger.warn("调用场馆返回空值。" + re.getMessage());
            }
        }
        else {
            if(respClubActivity.getActivityType() != 2)
            {
                PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                placeDubboProvider.setName(respClubActivity.getPlaceAddress());
                placeDubboProvider.setLat(respClubActivity.getLat());
                placeDubboProvider.setLng(respClubActivity.getLng());
                respClubActivity.setPlaceDubboProvider(placeDubboProvider);
            }
        }
    }

    public void getActivityPlaces(List<RespClubActivity> respClubActivities,
                                  Double lng, Double lat)
    {
        List<Integer> placeIds = new ArrayList<>();
        for(RespClubActivity respClubActivity : respClubActivities)
        {
            respClubActivity.setCurTime(new Date());
            if(null != lng && null != lat) {
                double latActivity = respClubActivity.getLat();
                double lngActivity = respClubActivity.getLng();
                Double activityDist = DistanceUtil.getDistanceRice(lngActivity, latActivity, lng, lat);
                respClubActivity.setDistance(activityDist);
            }
            TbActivityPoster tbActivityPoster = tbActivityPosterMapper.selectByPrimaryKey(respClubActivity.getPosterPicId());
            RespActivityPoster respActivityPoster = new RespActivityPoster();
            if (null != tbActivityPoster) {
                BeanCopierUtils.copyProperties(tbActivityPoster, respActivityPoster);
            }
            respClubActivity.setRespActivityPoster(respActivityPoster);
            respClubActivity.setLowestPrice(ActivityUtils.getLowestPrice(respClubActivity));
            placeIds.add(respClubActivity.getPlaceId());
        }
        //调场馆模块的接口 场馆
        Map<Integer, PlaceDubboProvider> placeMap = null;
        if(null != placeIds && placeIds.size() > 0)
        {
            try {
                placeMap = placeClient.getPlaceListByPlaceId(placeIds);
            } catch (RpcException re) {
                throw new BizException("调用场馆模块失败");
            }
        }
        for(RespClubActivity respClubActivity : respClubActivities)
        {
            if (null != respClubActivity.getPlaceId() &&
                    respClubActivity.getPlaceId() != 0 && null != placeMap) {
                if (null != placeMap.get(respClubActivity.getPlaceId())) {
                    PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                    BeanCopierUtils.copyProperties(placeMap.get(respClubActivity.getPlaceId()), placeDubboProvider);
                    respClubActivity.setPlaceDubboProvider(placeDubboProvider);
                }
            }
            else
            {
                if(respClubActivity.getActivityType() != 2)
                {
                    PlaceDubboProvider placeDubboProvider = new PlaceDubboProvider();
                    placeDubboProvider.setLat(respClubActivity.getLat());
                    placeDubboProvider.setLng(respClubActivity.getLng());
                    placeDubboProvider.setName(respClubActivity.getPlaceAddress());
                    placeDubboProvider.setPlaceId(0);
                    respClubActivity.setPlaceDubboProvider(placeDubboProvider);
                }
            }
        }
    }

    public void setRequireFields(String requireFields,
                                 ReqSignUpDetail reqSignUpInfo, TbSignUser tbSignUser)
    {
        if(null == requireFields || "".equals(requireFields))
        {
            return;
        }
        logger.warn("必填字段:" + requireFields);
        if(requireFields.contains("idCard") && null != reqSignUpInfo.getCardType())
        {
            tbSignUser.setCardType(reqSignUpInfo.getCardType());
        }
        if(requireFields.contains("birthday") && null != reqSignUpInfo.getBirthday())
        {
            tbSignUser.setBirthday(reqSignUpInfo.getBirthday());
        }
        Class clazz = tbSignUser.getClass();
        Class info = reqSignUpInfo.getClass();
        String[] fields = requireFields.split(",");
        for(String s : fields)
        {
            if(null == s || "".equals(s))
            {
                continue;
            }
            StringBuilder sb = new StringBuilder(s);
            sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
            s = sb.toString();
            String setMethod = "set" + s;
            String getMethod = "get" + s;
            try {
                Method method = clazz.getDeclaredMethod(setMethod, String.class);
                Method m = info.getDeclaredMethod(getMethod);
                String ss = (String)m.invoke(reqSignUpInfo);
                method.invoke(tbSignUser,ss);
            } catch (ReflectiveOperationException roe) {
                logger.warn("传入字段名不正确:" + requireFields + roe.getMessage());
            }
        }
        logger.warn("报名信息：" + JSONObject.toJSONString(tbSignUser));
    }

    public List<TbActivity> activityAfterWeek(int clubId)
    {
        Date weekStartTime = DateUtils.getTimesmorning();
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(weekStartTime);
        cal.add(Calendar.DAY_OF_WEEK, 7);
        Map<String, Object> map = Maps.newHashMap();
        map.put("clubId", clubId);
        map.put("weekStartTime", weekStartTime);
        map.put("weekEndTime", cal.getTime());
        List<TbActivity> activities = clubActivityCRUDMapper.selectAfterWeekActivity(map);
        return activities;
    }

    public int countActivityAfterWeek(int clubId)
    {
        Date weekStartTime = DateUtils.getTimesmorning();
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(weekStartTime);
        cal.add(Calendar.DAY_OF_WEEK, 7);
        Map<String, Object> map = Maps.newHashMap();
        map.put("clubId", clubId);
        map.put("weekStartTime", weekStartTime);
        map.put("weekEndTime", cal.getTime());
        return clubActivityCRUDMapper.countAfterWeekActivity(map);
    }

    public List<RespSearchActivity> searchActivityWithPlaceInfo(
            List<ActivitySearchResponse> list, List<Integer> clubIdList, List<Integer> removeActivityIds) {
        List<RespSearchActivity> searchActivityList = new ArrayList<>();
        List<Integer> activityIdList = new ArrayList<>();//活动id集合
        if (CollectionUtils.isEmpty(list)) {
            return searchActivityList;
        }
        logger.warn("去除重复展示的ID");
        for (ActivitySearchResponse activitySearchResponse : list) {
            if (null == activitySearchResponse.getActivityId() ||
                    "null".equals(activitySearchResponse.getActivityId())) {
                continue;
            }
            Integer activityId = Integer.parseInt(activitySearchResponse.getActivityId());
            if (null != removeActivityIds && removeActivityIds.contains(activityId)) {
                continue;
            }
            activityIdList.add(activityId);
        }
        Map<String, Object> freeMap = new HashMap<String, Object>();
        if(CollectionUtils.isEmpty(activityIdList))
        {
            return searchActivityList;
        }
        freeMap.put("activityIds", activityIdList);
        freeMap.put("isDelete", 0);
        freeMap.put("status", 0);
        //根据activityId查询respClubActivityList
        List<RespClubActivity> respClubActivityList =
                clubActivityCRUDMapper.queryClubActivityListByFree(freeMap);
        Map<Integer, RespClubActivity> respClubActivityMap = new HashMap<Integer, RespClubActivity>();
        for(RespClubActivity respClubActivity : respClubActivityList)
        {
            respClubActivityMap.put(respClubActivity.getActivityId(), respClubActivity);
        }
        //获取活动场馆
        getActivityPlaces(respClubActivityList, null, null);
        if (CollectionUtils.isEmpty(respClubActivityList)) {
            return searchActivityList;
        }
        Map<Integer, String> categoryMap = getCategoryMap();
        for (ActivitySearchResponse activitySearchResponse : list) {
            if ("null".equals(activitySearchResponse.getActivityId())) {
                continue;
            }
            int activityId = 0;
            try{
                activityId = Integer.valueOf(activitySearchResponse.getActivityId());
            }catch (NumberFormatException nfe){
                logger.warn("activityId错误:" + activitySearchResponse.getActivityId());
                continue;
            }
            RespSearchActivity respSearchActivity = new RespSearchActivity();
            BeanCopierUtils.copyProperties(activitySearchResponse, respSearchActivity);
            RespClubActivity respClubActivity = respClubActivityMap.get(activityId);
            if (null == respClubActivity) {
                continue;
            }
            respSearchActivity.setSignUpType(respClubActivity.getSignUpType());
            respSearchActivity.setActivityType(respClubActivity.getActivityType());
            respSearchActivity.setLat(activitySearchResponse.getLat());
            respSearchActivity.setLimitNum(respClubActivity.getLimitNum());
            respSearchActivity.setCategoryId(respClubActivity.getCategoryId());
            respSearchActivity.setAlreadySignTotalNum(respClubActivity.getAlreadySignTotalNum());
            respSearchActivity.setActivityClubName(respClubActivity.getClubName());
            respSearchActivity.setLogoUrl(respClubActivity.getLogoUrl());
            respSearchActivity.setActivitySite(respClubActivity.getPlaceAddress());
            respSearchActivity.setSquare(respClubActivity.getSquare());
            if(categoryMap.containsKey(respClubActivity.getCategoryId()))
            {
                respSearchActivity.setCategoryName(categoryMap.get(respClubActivity.getCategoryId()));
            }
            if(StringUtils.isEmpty(respSearchActivity.getCategoryName()))
            {
                respSearchActivity.setCategoryName("其他");
            }
            if (null != clubIdList && clubIdList.contains(respClubActivity.getClubId())) {
                respSearchActivity.setIsMine(1);//我的俱乐部的活动
            }
            if (null != respClubActivity.getPlaceId() && respClubActivity.getPlaceId() > 0) {
                PlaceDubboProvider placeDubboProvider = respClubActivity.getPlaceDubboProvider();
                if(placeDubboProvider != null) {
                    respSearchActivity.setPlaceDubboProvider(placeDubboProvider);
                    respSearchActivity.setActivitySite(
                            placeDubboProvider.getName());
                }
            }
            if(respClubActivity.getLimitNum() > 0 &&
                    respClubActivity.getLimitNum().equals(respClubActivity.getAlreadySignTotalNum()))
            {
                respSearchActivity.setActivityIsFull(1);
            }
            searchActivityList.add(respSearchActivity);
        }
        return searchActivityList;
    }

    public Map<Integer, String> getCategoryMap()
    {
        TbCategoryExample categoryExample = new TbCategoryExample();
        categoryExample.createCriteria().andIsDeleteEqualTo(Constants.BYTE_ZERO)
                .andIsEnableEqualTo(Constants.BYTE_ONE);
        List<TbCategory> categories = tbCategoryMapper.selectByExample(categoryExample);
        Map<Integer, String> categoryMap = new HashMap<Integer, String>();
        for(TbCategory category : categories)
        {
            categoryMap.put(category.getId(), category.getName());
        }
        return categoryMap;
    }

    public RespSearchActivity convertRespClubActivityToSearch(RespClubActivity respClubActivity) {
        RespSearchActivity respSearchActivity = new RespSearchActivity();
        respSearchActivity.setCategoryName(respClubActivity.getCategoryName());
        respSearchActivity.setActivityDist(respClubActivity.getDistance().floatValue());
        if(null == respClubActivity.getPlaceId() || respClubActivity.getPlaceId() == 0) {
            respSearchActivity.setActivitySite(respClubActivity.getPlaceAddress());
        } else {
            PlaceDubboProvider place = respClubActivity.getPlaceDubboProvider();
            if(null != place) {
                respSearchActivity.setActivitySite(place.getName());
            }
        }
        respSearchActivity.setActivityName(respClubActivity.getName());
        respSearchActivity.setActivityId(String.valueOf(respClubActivity.getActivityId()));
        respSearchActivity.setActivityStartTime(respClubActivity.getStartTime());
        respSearchActivity.setActivityPrice(
                respClubActivity.getLowestPrice().doubleValue());
        respSearchActivity.setSquare(respClubActivity.getSquare());
        TbActivityDescExample example = new TbActivityDescExample();
        example.createCriteria().
                andActivityIdEqualTo(respClubActivity.getActivityId());
        List<TbActivityDesc> activityDescs =
                tbActivityDescMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(activityDescs)) {
            return respSearchActivity;
        }
        TbActivityDesc tbActivityDesc = activityDescs.get(0);
        respSearchActivity.setActivityDetail(tbActivityDesc.getBodyDesc());
        return respSearchActivity;
    }
}
